
package com.neegix.system.user.interfaces.controller;

import com.neegix.base.PageVO;
import com.neegix.cqrs.command.UniversalCommandBus;
import com.neegix.cqrs.query.UniversalQueryBus;
import com.neegix.inferfaces.result.Result;
import com.neegix.infrastructure.utils.ExcelUtil;
import com.neegix.system.user.application.service.command.BindRolesCommand;
import com.neegix.system.user.application.service.command.CreateUserCommand;
import com.neegix.system.user.application.service.command.DeleteUserCommand;
import com.neegix.system.user.application.service.command.DisabledCommand;
import com.neegix.system.user.application.service.command.EnabledCommand;
import com.neegix.system.user.application.service.command.ModifyMinePasswordCommand;
import com.neegix.system.user.application.service.command.ResetPasswordCommand;
import com.neegix.system.user.application.service.command.UpdateUserCommand;
import com.neegix.system.user.application.service.command.mapper.UserCommandMapper;
import com.neegix.system.user.application.service.query.GetPageUserQuery;
import com.neegix.system.user.application.service.query.GetUserDetailQuery;
import com.neegix.system.user.application.service.query.GetUserQuery;
import com.neegix.system.user.application.service.query.GetUserRolesQuery;
import com.neegix.system.user.application.service.query.mapper.UserQueryMapper;
import com.neegix.system.user.interfaces.form.ImportUserForm;
import com.neegix.system.user.interfaces.form.ModifyPasswordForm;
import com.neegix.system.user.interfaces.form.NewUserForm;
import com.neegix.system.user.interfaces.form.QueryUserForm;
import com.neegix.system.user.interfaces.form.UpdateUserForm;
import com.neegix.system.user.interfaces.form.UserRolesForm;
import com.neegix.system.user.interfaces.vo.UserForExportVO;
import com.neegix.system.user.interfaces.vo.UserForListVO;
import com.neegix.system.user.interfaces.vo.UserVO;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
  * This file is auto-generated by nebula-framework-generator.
  * The auto-generation plugin was developed using IntelliJ IDEA Community Edition.
  * Thanks to JetBrains for their outstanding contributions to the developer community.
  * <p>
  * The code generated by this tool is owned by the user of the tool.
  * The tool itself is copyrighted by <a href="https://www.neegix.com">https://www.neegix.com</a>.
  *
  * @author <a href="https://www.neegix.com">https://www.neegix.com</a>
  * @version 1.0.0
  * @since 2024-12-03 11:47:28
  */

@RestController
@RequestMapping("/api/v1/user")
public class UserController {

    @Autowired
    private UniversalCommandBus universalCommandBus;

    @Autowired
    private UniversalQueryBus queryBus;

    @PreAuthorize("hasAuthority('system:user:add')")
    @PostMapping
    public Result<Void> createUser(@RequestBody @Valid NewUserForm userForm){
        CreateUserCommand command = UserCommandMapper.INSTANCE.covertCommand(userForm);
        return Result.success("创建成功", universalCommandBus.execute(command));
    }

    @PreAuthorize("hasAuthority('system:user:modify')")
    @PutMapping("/{id}")
    public Result<Void> updateUser(@PathVariable Long id, @RequestBody @Valid UpdateUserForm userForm){
        UpdateUserCommand command = UserCommandMapper.INSTANCE.covertCommand(userForm);
        command.setId(id);
        return Result.success("创建成功", universalCommandBus.execute(command));
    }

    @PreAuthorize("hasAuthority('system:user:list')")
    @GetMapping("/{currentPage}/{pageSize}")
    public Result<PageVO<UserForListVO>> getUsers(@PathVariable("currentPage") Integer currentPage, @PathVariable("pageSize") Integer pageSize, @ModelAttribute QueryUserForm userForm){
        if(userForm == null) {
            userForm = new QueryUserForm();
        }

        GetPageUserQuery query = UserQueryMapper.INSTANCE.covertToGetQuery(userForm);
        query.setCurrentPage(currentPage);
        query.setPageSize(pageSize);
        PageVO<UserForListVO> pageVO = queryBus.execute(query);
        return Result.success("查询成功",pageVO);
    }

    @PreAuthorize("hasAuthority('system:user:get')")
    @GetMapping("/{id}")
    public Result<UserVO> getUserById(@PathVariable("id") Long id) {
        return Result.success("获取成功", queryBus.execute(new GetUserDetailQuery(id)));
    }

    @PreAuthorize("hasAuthority('system:user:remove')")
    @DeleteMapping
    public Result<Void> removeUser(@RequestBody List<Long> ids){
        return Result.success("删除成功", universalCommandBus.execute(new DeleteUserCommand(ids)));
    }

    @PostMapping("/bindRoles")
    @PreAuthorize("hasAuthority('system:user:bindRoles')")
    public Result<Void> bindRoles(@RequestBody UserRolesForm userRolesForm) {
        BindRolesCommand bindRolesCommand = new BindRolesCommand(userRolesForm.getUserIds(), userRolesForm.getRoleIds());
        return Result.success("绑定成功！", universalCommandBus.execute(bindRolesCommand));
    }

    @GetMapping("/{pkUser}/roles")
    public Result<Set<Long>> rolesByUser(@PathVariable("pkUser") Long pkUser) {
        return Result.success("获取成功", queryBus.execute(new GetUserRolesQuery(pkUser)));
    }

    @PutMapping("/password")
    public Result<Void> modifyPassword(@RequestBody ModifyPasswordForm modifyPasswordForm) {
        ModifyMinePasswordCommand command = new ModifyMinePasswordCommand(modifyPasswordForm.getOldPassword(), modifyPasswordForm.getNewPassword(), modifyPasswordForm.getConfirmPassword());
        return Result.success("密码修改成功", universalCommandBus.execute(command));
    }

    @PutMapping("/resetPassword")
    public Result<String> resetPassword(@RequestBody List<Long> ids){
        ResetPasswordCommand command = new ResetPasswordCommand(ids);
        return Result.success("密码重置成功！", universalCommandBus.execute(command));
    }

    @PutMapping("/{pkUser}/enabled")
    public Result<Void> enabled(@PathVariable("pkUser") Long pkUser){
        universalCommandBus.execute(new EnabledCommand(pkUser));
        return Result.success();
    }

    @PutMapping("/{pkUser}/disabled")
    public Result<Void> disabled(@PathVariable("pkUser") Long pkUser){
        universalCommandBus.execute(new DisabledCommand(pkUser));
        return Result.success();
    }

    @PostMapping("/import")
    public Result<Void> importUsers(@RequestParam("file")MultipartFile file) throws IOException {
        List<ImportUserForm> importUserForms = new ArrayList<>();

        ExcelUtil.importExcel(file.getInputStream(), ImportUserForm.class, importUser -> {
            CreateUserCommand command = new CreateUserCommand();
            command.setName(importUser.getName());
            command.setEmail(importUser.getEmail());
            command.setDescription(importUser.getDescription());
            command.setMobilePhone(importUser.getMobilePhone());
            universalCommandBus.execute(command);
        });
        return Result.success();
    }

    @GetMapping("/export")
    public void exportUsers() throws IOException {
        // 1. 获取数据
        List<UserForExportVO> exportUsers =  queryBus.execute(new GetUserQuery());

        // 2. 调用导出工具
        ExcelUtil.export(exportUsers, "用户列表", "用户数据", UserForExportVO.class);
    }
}